//! Here we are following a "JSON-RPC 2.0" styleesponse with error or result.
//!
//! Notes:
//!     - For now, we do not handle the "request.id" of "JSON-RPC 2.0", and request batching
//!       but this could be added later.
//!     - The benefit of following the "JSON-RPC 2.0" scheme is that the frontend could be adapted to talk to a
//!       web server with minimum effort, and the JSON-RPC data format for request/response is simple, clean, and well thought out.

use anyhow::Result;
use serde::{Deserialize, Serialize};
use ts_rs::TS;

#[derive(Debug, Serialize, Deserialize, Default, TS)]
#[ts(export, export_to = "../../src/lib/bindings/IpcError.ts")]
struct IpcError {
    message: String,
}

#[derive(Debug, Serialize, Deserialize, Default, TS)]
#[ts(export, export_to = "../../src/lib/bindings/IpcSimpleResult.ts")]
pub struct IpcSimpleResult<D> {
    pub data: D,
}

#[derive(Debug, Serialize, Deserialize, Default, TS)]
#[ts(export, export_to = "../../src/lib/bindings/IpcResponse.ts")]
pub struct IpcResponse<D> {
    error: Option<IpcError>,
    result: Option<IpcSimpleResult<D>>,
}

impl<D> From<Result<D>> for IpcResponse<D>
where
    D: Serialize,
{
    fn from(res: Result<D>) -> Self {
        match res {
            Ok(data) => IpcResponse {
                error: None,
                result: Some(IpcSimpleResult { data }),
            },
            Err(err) => IpcResponse {
                error: Some(IpcError {
                    message: format!("{err}"),
                }),
                result: None,
            },
        }
    }
}
